package com.wsl.sale.configuration;

import com.alibaba.druid.pool.DruidDataSource;
import com.dangdang.ddframe.rdb.sharding.api.ShardingDataSourceFactory;
import com.dangdang.ddframe.rdb.sharding.api.rule.DataSourceRule;
import com.dangdang.ddframe.rdb.sharding.api.rule.ShardingRule;
import com.dangdang.ddframe.rdb.sharding.api.rule.TableRule;
import com.dangdang.ddframe.rdb.sharding.api.strategy.database.DatabaseShardingStrategy;
import com.dangdang.ddframe.rdb.sharding.api.strategy.table.TableShardingStrategy;
import com.sun.corba.se.spi.ior.ObjectKey;
import com.wsl.sale.utils.DataSourceEnum;
import com.wsl.sale.utils.ShardingDataSourceUtils;
import com.wsl.sale.utils.ShardingTableutils;
import com.wsl.sale.utils.TableEnum;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.core.RedisTemplate;

import javax.sql.DataSource;
import java.sql.SQLException;
import java.util.*;

@Configuration
public class DataSourceConfig {


    @Bean
    public DataSource buildDataSource() throws SQLException {
        //1.设置分库映射
        Map<String,DataSource> dataSourceMap = new HashMap<>(DataSourceEnum.values().length);
        for (DataSourceEnum dataSourceEnum : DataSourceEnum.values()) {
            dataSourceMap.put(dataSourceEnum.getValue(),createDataSource(dataSourceEnum.getValue()));
        }
        //设置默认db为ds_0,也就是为那些没有配置分库分表策略的指定默认库
        //如果只有一个库也就不需要分库的话。map里只放一个映射就行了。只有一个库时不需要指定默认的库
        //但2个及以上时必须指定默认库，否则那些没有配置策略的表将无法操作数据
        DataSourceRule rule = new DataSourceRule(dataSourceMap,DataSourceEnum.DS_0.getValue());
        // 2.设置分表映射，将t_order_0 和t_order_1 两个实际的表映射到t_order逻辑表
        List<String> tableList = new ArrayList<>();
        for (TableEnum value : TableEnum.values()) {
            tableList.add(value.getValue());
        }
        TableRule orderTableRule = TableRule.builder("t_order").actualTables(tableList).dataSourceRule(rule).build();
        //3.具体的分库分表策略
        ShardingRule shardingRule = ShardingRule.builder().dataSourceRule(rule)
                .tableRules(Arrays.asList(orderTableRule))
                .databaseShardingStrategy(new DatabaseShardingStrategy("user_id",new ShardingDataSourceUtils()))  //分库使用
                .tableShardingStrategy(new TableShardingStrategy("order_id",new ShardingTableutils())).build(); //分表使用

        DataSource dataSource = ShardingDataSourceFactory.createDataSource(shardingRule);
        return dataSource;
    }

    private static DataSource createDataSource(String dataSourceName) {
        //使用druid连接数据库
        DruidDataSource druidDataSource = new DruidDataSource();
        druidDataSource.setDriverClassName("com.mysql.jdbc.Driver");
        druidDataSource.setUrl(String.format("jdbc:mysql://localhost:3306/%s?serverTimezone=UTC&characterEncoding=utf-8",dataSourceName));
        druidDataSource.setUsername("root");
        druidDataSource.setPassword("qwer1234");
        return druidDataSource;

    }

}
